/*
 * Copyright 2022 Rich yang, 18158898020@189.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

`include "defines.v"

module regfile(
	input wire clk,
	input wire rst,

	// write port
	input wire		we,
	input wire[`RegAddrBus] waddr,
	input wire[`RegBus]	wdata,

	// read port 1
	input wire		re1,
	input wire[`RegAddrBus] raddr1,
	output reg[`RegBus]	rdata1,

	// read port 2
	input wire		re2,
	input wire[`RegAddrBus] raddr2,
	output reg[`RegBus]	rdata2
);

// stage1: defines 32 bit32 register
reg [`RegBus] regs[0:`RegNum-1];

// stage2: write operate
	always @ (posedge clk) begin
		if (rst == `RstDisable) begin
			if ((we == `WriteEnable) && (waddr != `RegNumLog2'h0)) begin
				regs[waddr] <= wdata;
			end
		end
	end

// stage3: read port1 operate
	always @ (*) begin
		if (rst == `RstEnable) begin
			rdata1 <= `ZeroWord;
		end else if (raddr1 == `RegNumLog2'h0) begin
			rdata1 <= `ZeroWord;
		end else if ((raddr1 == waddr) && (we == `WriteEnable)
				&& (re1 == `ReadEnable)) begin
			rdata1 <= wdata;
		end else if (re1 == `ReadEnable) begin
			rdata1 <= regs[raddr1];
		end else begin
			rdata1 <= `ZeroWord;
		end
	end

// stage4: read port2 operate
	always @ (*) begin
		if (rst == `RstEnable) begin
			rdata2 <= `ZeroWord;
		end else if (raddr2 == `RegNumLog2'h0) begin
			rdata2 <= `ZeroWord;
		end else if ((raddr2 == waddr) && (we == `WriteEnable)
				&& (re2 == `ReadEnable)) begin
			rdata2 <= wdata;
		end else if (re2 == `ReadEnable) begin
			rdata2 <= regs[raddr2];
		end else begin
			rdata2 <= `ZeroWord;
		end
	end


endmodule
